from logging.config import dictConfig
import logging
import os
from logging.handlers import TimedRotatingFileHandler
from pathlib import Path
from datetime import datetime


class RelativePathFormatter(logging.Formatter):
    def __init__(self, *args, project_root: str = None, **kwargs):
        super().__init__(*args, **kwargs)
        # 把项目根目录传进来
        self.project_root = project_root or os.getcwd()

    def format(self, record: logging.LogRecord) -> str:
        record.rel_path = os.path.relpath(record.pathname, self.project_root)
        return super().format(record)


class DailyRotatingFileHandler(TimedRotatingFileHandler):
    """按日期滚动的文件处理器"""

    def __init__(self, filename, when='midnight', interval=1, backupCount=30, encoding='utf-8'):
        # 创建日志目录
        log_dir = Path(filename).parent
        log_dir.mkdir(exist_ok=True)

        super().__init__(
            filename=filename,
            when=when,
            interval=interval,
            backupCount=backupCount,
            encoding=encoding
        )


# 项目根目录
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
LOG_DIR = os.path.join(PROJECT_ROOT, "logs")

# 确保日志目录存在
os.makedirs(LOG_DIR, exist_ok=True)

# 日志文件路径
APP_LOG_FILE = os.path.join(LOG_DIR, "app.log")
ACCESS_LOG_FILE = os.path.join(LOG_DIR, "access.log")
ERROR_LOG_FILE = os.path.join(LOG_DIR, "error.log")

LOGGING_CONFIG = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "default": {
            "()": RelativePathFormatter,
            "fmt": "%(asctime)s.%(msecs)03d | %(levelname)s | %(name)s | %(rel_path)s:%(lineno)d | %(message)s",
            "datefmt": "%Y-%m-%d %H:%M:%S",
            "project_root": PROJECT_ROOT
        },
        "simple": {
            "fmt": "%(asctime)s | %(levelname)s | %(message)s",
            "datefmt": "%Y-%m-%d %H:%M:%S"
        },
    },
    "handlers": {
        "console": {
            "formatter": "default",
            "class": "logging.StreamHandler",
            "stream": "ext://sys.stdout",
        },
        "file_app": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "formatter": "default",
            "filename": APP_LOG_FILE,
            "when": "midnight",
            "interval": 1,
            "backupCount": 30,
            "encoding": "utf-8",
            "utc": False
        },
        "file_access": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "formatter": "simple",
            "filename": ACCESS_LOG_FILE,
            "when": "midnight",
            "interval": 1,
            "backupCount": 30,
            "encoding": "utf-8",
            "utc": False
        },
        "file_error": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "formatter": "default",
            "filename": ERROR_LOG_FILE,
            "when": "midnight",
            "interval": 1,
            "backupCount": 30,
            "encoding": "utf-8",
            "level": "ERROR",
            "utc": False
        },
    },
    "loggers": {
        # 根日志记录器 - 捕获所有日志
        # "": {
        #     "handlers": ["console", "file_app", "file_error"],
        #     "level": "INFO",
        #     "propagate": False
        # },
        # Uvicorn 日志
        "uvicorn": {
            "handlers": ["console", "file_app"],
            "level": "INFO",
            "propagate": False
        },
        "uvicorn.error": {
            "handlers": ["console", "file_error"],
            "level": "ERROR",
            "propagate": False
        },
        "uvicorn.access": {
            "handlers": ["console", "file_access"],
            "level": "INFO",
            "propagate": False
        },
        # 应用特定日志记录器
        "capcut": {
            "handlers": ["console", "file_app", "file_error"],
            "level": "INFO",
            "propagate": False
        }
    },
}

# 应用日志配置
dictConfig(LOGGING_CONFIG)

# 获取日志记录器
logger = logging.getLogger(__name__)


def get_logger(name: str = None):
    """获取指定名称的日志记录器"""
    return logging.getLogger(name) if name else logger